package de.laures.cewolf.style;

import java.awt.Color;
import java.awt.Paint;
import java.awt.Polygon;
import java.awt.Shape;
import java.awt.geom.Ellipse2D;
import java.awt.geom.Rectangle2D;
import java.util.List;

import org.jfree.chart.plot.DefaultDrawingSupplier;

import de.laures.cewolf.util.PropReader;

public class CustomDrawSupplier extends DefaultDrawingSupplier {

	public static final Paint[] DEFAULT_PAINT_SEQUENCE = getCustomPaintSequence();

	public static final Shape[] DEFAULT_SHAPE_SEQUENCE = createStandardSeriesShapes();

	public CustomDrawSupplier() {
		super(DEFAULT_PAINT_SEQUENCE, DEFAULT_FILL_PAINT_SEQUENCE, DEFAULT_OUTLINE_PAINT_SEQUENCE,
				DEFAULT_STROKE_SEQUENCE, DEFAULT_OUTLINE_STROKE_SEQUENCE, DEFAULT_SHAPE_SEQUENCE);

	}

	public CustomDrawSupplier(boolean allSame, double shapeSize) {
		super(DEFAULT_PAINT_SEQUENCE, DEFAULT_FILL_PAINT_SEQUENCE, DEFAULT_OUTLINE_PAINT_SEQUENCE,
				DEFAULT_STROKE_SEQUENCE, DEFAULT_OUTLINE_STROKE_SEQUENCE,
				createStandardSeriesShapes(allSame, shapeSize));
	}

	public static Paint[] getCustomPaintSequence() {
		List<Color> list = PropReader.instance.getColorList(StyleConstants.COLOR_LIST);
		return list.toArray(new Paint[] {});

	}

	public static Shape[] createStandardSeriesShapes(boolean allSame, double size) {
		Shape[] result = null;
		if (allSame) {
			result = new Shape[1];
			double delta = size / 2.0;
			// circle
			result[0] = new Ellipse2D.Double(-delta, -delta, size, size);
		}
		else {
			result = new Shape[10];
			double delta = size / 2.0;
			int[] xpoints = null;
			int[] ypoints = null;

			// circle
			result[0] = new Ellipse2D.Double(-delta, -delta, size, size);
			// square
			result[1] = new Rectangle2D.Double(-delta, -delta, size, size);

			// up-pointing triangle
			xpoints = intArray(0.0, delta, -delta);
			ypoints = intArray(-delta, delta, delta);
			result[2] = new Polygon(xpoints, ypoints, 3);

			// diamond
			xpoints = intArray(0.0, delta, 0.0, -delta);
			ypoints = intArray(-delta, 0.0, delta, 0.0);
			result[3] = new Polygon(xpoints, ypoints, 4);

			// horizontal rectangle
			result[4] = new Rectangle2D.Double(-delta, -delta / 2, size, size / 2);

			// down-pointing triangle
			xpoints = intArray(-delta, +delta, 0.0);
			ypoints = intArray(-delta, -delta, delta);
			result[5] = new Polygon(xpoints, ypoints, 3);

			// horizontal ellipse
			result[6] = new Ellipse2D.Double(-delta, -delta / 2, size, size / 2);

			// right-pointing triangle
			xpoints = intArray(-delta, delta, -delta);
			ypoints = intArray(-delta, 0.0, delta);
			result[7] = new Polygon(xpoints, ypoints, 3);

			// vertical rectangle
			result[8] = new Rectangle2D.Double(-delta / 2, -delta, size / 2, size);

			// left-pointing triangle
			xpoints = intArray(-delta, delta, delta);
			ypoints = intArray(0.0, -delta, +delta);
			result[9] = new Polygon(xpoints, ypoints, 3);
		}
		return result;
	}

	public static Shape[] createStandardSeriesShapes() {
		double size = PropReader.instance.getDouble(StyleConstants.SHAPE_SIZE);
		boolean allSame = PropReader.instance.getBoolean(StyleConstants.SHAPE_ALLSAME);
		return createStandardSeriesShapes(allSame, size);

	}

	private static int[] intArray(double a, double b, double c) {
		return new int[] { (int) a, (int) b, (int) c };
	}

	private static int[] intArray(double a, double b, double c, double d) {
		return new int[] { (int) a, (int) b, (int) c, (int) d };
	}
}
